package tms.ui;

import org.eclipse.core.databinding.DataBindingContext;
import org.eclipse.core.databinding.beans.BeanProperties;
import org.eclipse.core.databinding.beans.BeansObservables;
import org.eclipse.core.databinding.beans.IBeanValueProperty;
import org.eclipse.core.databinding.observable.Realm;
import org.eclipse.core.databinding.observable.list.IObservableList;
import org.eclipse.core.databinding.observable.map.IObservableMap;
import org.eclipse.core.databinding.property.value.IValueProperty;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.action.StatusLineManager;
import org.eclipse.jface.action.ToolBarManager;
import org.eclipse.jface.databinding.swt.SWTObservables;
import org.eclipse.jface.databinding.swt.WidgetProperties;
import org.eclipse.jface.databinding.viewers.CellEditorProperties;
import org.eclipse.jface.databinding.viewers.ObservableListContentProvider;
import org.eclipse.jface.databinding.viewers.ObservableListTreeContentProvider;
import org.eclipse.jface.databinding.viewers.ObservableMapLabelProvider;
import org.eclipse.jface.databinding.viewers.ObservableValueEditingSupport;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.layout.TableColumnLayout;
import org.eclipse.jface.layout.TreeColumnLayout;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.ColumnPixelData;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.jface.viewers.TextCellEditor;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.window.ApplicationWindow;
import org.eclipse.nebula.widgets.ganttchart.themes.ColorThemeSilver;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.wb.rcp.databinding.BeansListObservableFactory;
import org.eclipse.wb.rcp.databinding.TreeBeanAdvisor;
import org.eclipse.wb.rcp.databinding.TreeObservableLabelProvider;
import org.eclipse.wb.swt.ResourceManager;

import tms.model.Person;
import tms.model.Project;
import tms.model.Task;

public class Main extends ApplicationWindow {
	private DataBindingContext m_bindingContext;

	private Project project = Project.getInstance();

	// actions
	private Action actionHelpAbout;
	private Action actionFileExit;
	private Action actionFileExportPeople;
	private Action actionFileExportTasks;
	private Action actionFileOpen;
	private Action actionFileSave;
	private Action actionEditNewProject;
	private Action actionEditAddTask;
	private Action actionEditAddSubtask;
	private Action actionEditRemoveTask;

	// widths for table columns
	final static int WIDTH_ID = 35;
	final static int WIDTH_BEFORE_ID = 60;
	final static int WIDTH_TITLE = 90;
	final static int WIDTH_DESCRIPTION = 120;
	final static int WIDTH_DURATION = 60;
	final static int WIDTH_DELIVERABLE = 140;
	final static int WIDTH_DEADLINE = 170;
	final static int WIDTH_PERSON = 90;
	final static int WIDTH_NAME = 90;
	final static int WIDTH_HOURS = 40;
	final static int WIDTH_TASKS = 100;

	// treeviewer
	private TreeViewer treeViewerTasks;

	// table viewers and columns
	private Table tablePeople;
	private TableViewer tableViewerPeople;
	private TableViewerColumn tableViewerColumnName;
	private TableViewerColumn tableViewerColumnHours;
	private TableViewerColumn tableViewerColumnTasks;
	private Table tableTasks;
	private TableViewer tableViewerTasks;
	private TableViewerColumn tableViewerColumnId;
	private TableViewerColumn tableViewerColumnTitle;
	private TableViewerColumn tableViewerColumnDescription;
	private TableViewerColumn tableViewerColumnDuration;
	private TableViewerColumn tableViewerColumnDeadline;
	private TableViewerColumn tableViewerColumnDeliverable;
	private TableViewerColumn tableViewerColumnBeforeId;
	private TableViewerColumn tableViewerColumnPerson;

	// Gantt chart
	private TMSGanttChart ganttChart;

	/**
	 * Create the application window.
	 */
	public Main() {
		super(null);

		ApplicationWindow.setDefaultImage(ResourceManager.getImage(ResourceManager.getImageDescriptor(Main.class, "/images/calendar-task.png")));
		createActions();
		addToolBar(SWT.FLAT | SWT.WRAP);
		addMenuBar();
		addStatusLine();
	}

	/**
	 * Create contents of the application window.
	 * 
	 * @param parent
	 */
	@Override
	protected Control createContents(Composite parent) {
		Composite container = new Composite(parent, SWT.NONE);
		container.setLayout(new FillLayout(SWT.HORIZONTAL));

		SashForm sashFormMain = new SashForm(container, SWT.VERTICAL);

		SashForm sashFormTop = new SashForm(sashFormMain, SWT.NONE);

		Composite compositeTree = new Composite(sashFormTop, SWT.NONE);
		compositeTree.setLayout(new TreeColumnLayout());

		treeViewerTasks = new TreeViewer(compositeTree, SWT.BORDER);
		treeViewerTasks.setAutoExpandLevel(10);

		SashForm sashFormRight = new SashForm(sashFormTop, SWT.VERTICAL);

		Composite compositeTableTasks = new Composite(sashFormRight, SWT.NONE);
		TableColumnLayout tcl_compositeTableTasks = new TableColumnLayout();
		compositeTableTasks.setLayout(tcl_compositeTableTasks);

		tableViewerTasks = new TableViewer(compositeTableTasks, SWT.BORDER | SWT.FULL_SELECTION);
		tableTasks = tableViewerTasks.getTable();
		tableTasks.setHeaderVisible(true);
		tableTasks.setLinesVisible(true);

		tableViewerColumnId = new TableViewerColumn(tableViewerTasks, SWT.NONE);
		TableColumn tblclmnId = tableViewerColumnId.getColumn();
		tcl_compositeTableTasks.setColumnData(tblclmnId, new ColumnPixelData(WIDTH_ID, true, true));
		tblclmnId.setText("ID");

		tableViewerColumnTitle = new TableViewerColumn(tableViewerTasks, SWT.NONE);
		TableColumn tblclmnTitle = tableViewerColumnTitle.getColumn();
		tcl_compositeTableTasks.setColumnData(tblclmnTitle, new ColumnPixelData(WIDTH_TITLE, true, true));
		tblclmnTitle.setText("Title");

		tableViewerColumnDescription = new TableViewerColumn(tableViewerTasks, SWT.NONE);
		TableColumn tblclmnDescription = tableViewerColumnDescription.getColumn();
		tcl_compositeTableTasks.setColumnData(tblclmnDescription, new ColumnPixelData(WIDTH_DESCRIPTION, true, true));
		tblclmnDescription.setText("Description");

		tableViewerColumnDuration = new TableViewerColumn(tableViewerTasks, SWT.NONE);
		TableColumn tblclmnDuration = tableViewerColumnDuration.getColumn();
		tcl_compositeTableTasks.setColumnData(tblclmnDuration, new ColumnPixelData(WIDTH_DURATION, true, true));
		tblclmnDuration.setText("Duration");

		tableViewerColumnDeadline = new TableViewerColumn(tableViewerTasks, SWT.NONE);
		TableColumn tblclmnDeadline = tableViewerColumnDeadline.getColumn();
		tcl_compositeTableTasks.setColumnData(tblclmnDeadline, new ColumnPixelData(WIDTH_DEADLINE, true, true));
		tblclmnDeadline.setText("Deadline");

		tableViewerColumnDeliverable = new TableViewerColumn(tableViewerTasks, SWT.NONE);
		TableColumn tblclmnDeliverable = tableViewerColumnDeliverable.getColumn();
		tcl_compositeTableTasks.setColumnData(tblclmnDeliverable, new ColumnPixelData(WIDTH_DELIVERABLE, true, true));
		tblclmnDeliverable.setText("Deliverable");

		tableViewerColumnBeforeId = new TableViewerColumn(tableViewerTasks, SWT.NONE);
		TableColumn tblclmnBeforeId = tableViewerColumnBeforeId.getColumn();
		tcl_compositeTableTasks.setColumnData(tblclmnBeforeId, new ColumnPixelData(WIDTH_BEFORE_ID, true, true));
		tblclmnBeforeId.setText("Before ID");

		tableViewerColumnPerson = new TableViewerColumn(tableViewerTasks, SWT.NONE);
		TableColumn tblclmnPerson = tableViewerColumnPerson.getColumn();
		tcl_compositeTableTasks.setColumnData(tblclmnPerson, new ColumnWeightData(WIDTH_PERSON));
		tblclmnPerson.setText("Person");

		Composite compositeTablePeople = new Composite(sashFormRight, SWT.NONE);
		TableColumnLayout tcl_compositeTablePeople = new TableColumnLayout();
		compositeTablePeople.setLayout(tcl_compositeTablePeople);

		tableViewerPeople = new TableViewer(compositeTablePeople, SWT.BORDER | SWT.FULL_SELECTION);
		tablePeople = tableViewerPeople.getTable();
		tablePeople.setHeaderVisible(true);
		tablePeople.setLinesVisible(true);

		tableViewerColumnName = new TableViewerColumn(tableViewerPeople, SWT.NONE);
		TableColumn tblclmnName = tableViewerColumnName.getColumn();
		tcl_compositeTablePeople.setColumnData(tblclmnName, new ColumnPixelData(WIDTH_NAME, true, true));
		tblclmnName.setText("Name");

		tableViewerColumnHours = new TableViewerColumn(tableViewerPeople, SWT.NONE);
		TableColumn tblclmnHours = tableViewerColumnHours.getColumn();
		tcl_compositeTablePeople.setColumnData(tblclmnHours, new ColumnPixelData(WIDTH_HOURS, true, true));
		tblclmnHours.setText("Hours");

		tableViewerColumnTasks = new TableViewerColumn(tableViewerPeople, SWT.NONE);
		TableColumn tblclmnTasks = tableViewerColumnTasks.getColumn();
		tcl_compositeTablePeople.setColumnData(tblclmnTasks, new ColumnWeightData(WIDTH_TASKS));
		tblclmnTasks.setText("Tasks");

		sashFormRight.setWeights(new int[] { 3, 2 });

		sashFormTop.setWeights(new int[] { 1, 3 });
		ganttChart = new TMSGanttChart(sashFormMain, SWT.NONE, null, new ColorThemeSilver(), null, null);
		project.addPropertyChangeListener(ganttChart);

		sashFormMain.setWeights(new int[] { 3, 2 });

		m_bindingContext = initDataBindings();

		return container;
	}

	/**
	 * Create the actions.
	 */
	private void createActions() {
		// Create the actions
		// about
		{
			actionHelpAbout = new Action("About") {
				public void run() {
					About aboutDialog = new About(getShell());
					aboutDialog.open();
				}
			};
			actionHelpAbout.setToolTipText("Displays information about the application");
			actionHelpAbout.setImageDescriptor(ResourceManager.getImageDescriptor(Main.class, "/images/information-frame.png"));
		}
		// exit application
		{
			actionFileExit = new Action("Exit") {
				public void run() {
					close();
				}
			};
			actionFileExit.setAccelerator(SWT.CTRL | 'W');
			actionFileExit.setToolTipText("Exits the application");
			actionFileExit.setImageDescriptor(ResourceManager.getImageDescriptor(Main.class, "/images/control-power.png"));
		}
		// export people data
		{
			actionFileExportPeople = new Action("Export people") {
				public void run() {
					if (savePeopleFile()) {
						setStatus("Exported people file successfully");
					}
				}
			};
			actionFileExportPeople.setToolTipText("Exports people information to a csv file");
			actionFileExportPeople.setImageDescriptor(ResourceManager.getImageDescriptor(Main.class, "/images/user-small-female-save.png"));
		}
		// export tasks data
		{
			actionFileExportTasks = new Action("Export tasks") {
				public void run() {
					if (saveTasksFile()) {
						setStatus("Exported tasks file successfully");
					}
				}
			};
			actionFileExportTasks.setToolTipText("Exports tasks to a csv file");
			actionFileExportTasks.setImageDescriptor(ResourceManager.getImageDescriptor(Main.class, "/images/document-exports-tasks.png"));
		}
		// open project file
		{
			actionFileOpen = new Action("Open file...") {
				public void run() {
					if (openProjectFile()) {
						setStatus("Project file opened successfully");
					}
				}
			};
			actionFileOpen.setAccelerator(SWT.CTRL | 'O');
			actionFileOpen.setToolTipText("Opens a task management project file");
			actionFileOpen.setImageDescriptor(ResourceManager.getImageDescriptor(Main.class, "/images/folder-horizontal-open.png"));
		}
		// save project file
		{
			actionFileSave = new Action("Save file") {
				public void run() {
					if (saveProjectFile()) {
						setStatus("Saved project file successfully");
					}
				}
			};
			actionFileSave.setAccelerator(SWT.CTRL | 'S');
			actionFileSave.setImageDescriptor(ResourceManager.getImageDescriptor(Main.class, "/images/disk.png"));
			actionFileSave.setToolTipText("Saves the project to an XML file");
		}
		// add task to the project
		{
			actionEditAddTask = new Action("Add task") {
				public void run() {
					project.addTask();
					setStatus("Task added");
				}
			};
			actionEditAddTask.setAccelerator(SWT.KEYPAD_ADD);
			actionEditAddTask.setImageDescriptor(ResourceManager.getImageDescriptor(Main.class, "/images/node-insert-next.png"));
			actionEditAddTask.setToolTipText("Adds a new task to the task tree");
		}
		// add subtask to the currently selected task
		{
			actionEditAddSubtask = new Action("Add subtask") {
				public void run() {
					IStructuredSelection selection = (IStructuredSelection) treeViewerTasks.getSelection();
					// this can return null
					Task task = (Task) selection.getFirstElement();
					if (task != null) {
						project.addSubtask(task);
						treeViewerTasks.expandAll();
						setStatus("Subtask added");
					}
				}
			};
			actionEditAddSubtask.setAccelerator(SWT.KEYPAD_MULTIPLY);
			actionEditAddSubtask.setImageDescriptor(ResourceManager.getImageDescriptor(Main.class, "/images/node-insert-child.png"));
			actionEditAddSubtask.setToolTipText("Adds a subtask to the currently selected task");
		}
		// remove currently selected task/subtask
		{
			actionEditRemoveTask = new Action("Remove task") {
				public void run() {
					IStructuredSelection selection = (IStructuredSelection) treeViewerTasks.getSelection();
					// this can return null
					Task task = (Task) selection.getFirstElement();
					if (task != null) {
						project.removeTask(task);
						treeViewerTasks.expandAll();
						setStatus("Task removed");
					}
				}
			};
			actionEditRemoveTask.setAccelerator(SWT.KEYPAD_SUBTRACT);
			actionEditRemoveTask.setImageDescriptor(ResourceManager.getImageDescriptor(Main.class, "/images/node-delete.png"));
			actionEditRemoveTask.setToolTipText("Removes the selected task from the project");
		}
		// create a new, empty project
		{
			actionEditNewProject = new Action("New project") {
				public void run() {
					project.clear();
					setStatus("New project created");
				}
			};
			actionEditNewProject.setAccelerator(SWT.CTRL | 'N');
			actionEditNewProject.setImageDescriptor(ResourceManager.getImageDescriptor(Main.class, "/images/new.png"));
			actionEditNewProject.setToolTipText("Creates a new project");
		}
	}

	/**
	 * Create the menu manager.
	 * 
	 * @return the menu manager
	 */
	@Override
	protected MenuManager createMenuManager() {
		MenuManager menuManager = new MenuManager("menu");

		MenuManager menuManagerFile = new MenuManager("File");
		menuManager.add(menuManagerFile);
		menuManagerFile.add(actionFileOpen);
		menuManagerFile.add(new Separator());
		menuManagerFile.add(actionFileSave);
		menuManagerFile.add(actionFileExportTasks);
		menuManagerFile.add(actionFileExportPeople);
		menuManagerFile.add(new Separator());
		menuManagerFile.add(actionFileExit);

		MenuManager menuManagerEdit = new MenuManager("Edit");
		menuManager.add(menuManagerEdit);
		menuManagerEdit.add(actionEditNewProject);
		menuManagerEdit.add(new Separator());
		menuManagerEdit.add(actionEditAddTask);
		menuManagerEdit.add(actionEditAddSubtask);
		menuManagerEdit.add(actionEditRemoveTask);

		MenuManager menuManagerHelp = new MenuManager("Help");
		menuManager.add(menuManagerHelp);
		menuManagerHelp.add(actionHelpAbout);
		return menuManager;
	}

	/**
	 * Create the toolbar manager.
	 * 
	 * @return the toolbar manager
	 */
	@Override
	protected ToolBarManager createToolBarManager(int style) {
		ToolBarManager toolBarManager = new ToolBarManager(style);
		toolBarManager.add(actionFileOpen);
		toolBarManager.add(new Separator());
		toolBarManager.add(actionFileSave);
		toolBarManager.add(actionFileExportTasks);
		toolBarManager.add(actionFileExportPeople);
		toolBarManager.add(new Separator());
		toolBarManager.add(actionEditNewProject);
		toolBarManager.add(actionEditAddTask);
		toolBarManager.add(actionEditAddSubtask);
		toolBarManager.add(actionEditRemoveTask);
		return toolBarManager;
	}

	/**
	 * Create the status line manager.
	 * 
	 * @return the status line manager
	 */
	@Override
	protected StatusLineManager createStatusLineManager() {
		StatusLineManager statusLineManager = new StatusLineManager();
		return statusLineManager;
	}

	/**
	 * Launch the application.
	 * 
	 * @param args
	 */
	public static void main(String args[]) {
		Display display = Display.getDefault();
		Realm.runWithDefault(SWTObservables.getRealm(display), new Runnable() {
			public void run() {
				try {
					Main window = new Main();
					window.setBlockOnOpen(true);
					window.open();

					Display.getCurrent().dispose();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Configure the shell.
	 * 
	 * @param newShell
	 */
	@Override
	protected void configureShell(Shell newShell) {
		super.configureShell(newShell);

		newShell.setMinimumSize(700, 500);
		newShell.setSize(1100, 600);
		newShell.setText("Task Management System - TMS");
		setStatus("COMP5541 Group 3");
	}

	/**
	 * Return the initial size of the window.
	 */
	@Override
	protected Point getInitialSize() {
		return new Point(1100, 600);
	}

	/**
	 * Open a project file.
	 * 
	 * @return true if a file was opened successfully
	 */
	private boolean openProjectFile() {
		String selectedFile = getOpenFileNameXML();
		if (selectedFile != null) {
			if (project.loadProjectFile(selectedFile)) {
				treeViewerTasks.expandAll();
				return true;
			}
			else {
				MessageDialog.openInformation(getShell(), "Invalid file", "The file " + selectedFile + " could not be opened.");
			}
		} else {
			MessageDialog.openInformation(getShell(), "Invalid file", "The file does not exist.");
		}
		return false;
	}

	/**
	 * Save the people table to a file.
	 * 
	 * @return true if a file was saved successfully
	 */
	private boolean saveProjectFile() {
		String selectedFile = getSaveFileNameXML("Save project file as");
		if (selectedFile != null) {
			if (project.saveProjectFile(selectedFile)) {
				return true;
			} else {
				MessageDialog.openInformation(getShell(), "Invalid file", "The file " + selectedFile + " could not be saved.");
			}
		} else {
			MessageDialog.openInformation(getShell(), "Invalid file", "The file could not be saved.");
		}
		return false;
	}

	/**
	 * Save the people table to a file.
	 * 
	 * @return true if a file was saved successfully
	 */
	private boolean savePeopleFile() {
		String selectedFile = getSaveFileNameCSV("Save people file as");
		if (selectedFile != null) {
			if (project.savePeopleList(selectedFile)) {
				return true;
			} else {
				MessageDialog.openInformation(getShell(), "Invalid file", "The file " + selectedFile + " could not be saved.");
			}
		} else {
			MessageDialog.openInformation(getShell(), "Invalid file", "The file could not be saved.");
		}
		return false;
	}

	/**
	 * Save the tasks table to a file.
	 * 
	 * @return true if a file was saved successfully
	 */
	private boolean saveTasksFile() {
		String selectedFile = getSaveFileNameCSV("Save tasks file as");
		if (selectedFile != null) {
			if (project.saveTaskList(selectedFile)) {
				return true;
			} else {
				MessageDialog.openInformation(getShell(), "Invalid file", "The file " + selectedFile + " could not be saved.");
			}
		} else {
			MessageDialog.openInformation(getShell(), "Invalid file", "The file could not be saved.");
		}
		return false;
	}

	/**
	 * Display a save file dialog and retrieve filename
	 * 
	 * @return filename of selected file
	 */
	private String getSaveFileNameXML(String title) {
		FileDialog fileDialog = new FileDialog(getShell(), SWT.SAVE);
		fileDialog.setText(title);
		fileDialog.setFilterExtensions(new String[] { "*.xml" });
		fileDialog.setFilterNames(new String[] { "XML files (*.xml)" });
		// Open Dialog and save result of selection
		String selectedFile = fileDialog.open();
		if (selectedFile == null) {
			return null;
		}
		return selectedFile;
	}

	/**
	 * Display a save file dialog and retrieve filename
	 * 
	 * @return filename of selected file
	 */
	private String getSaveFileNameCSV(String title) {
		FileDialog fileDialog = new FileDialog(getShell(), SWT.SAVE);
		fileDialog.setText(title);
		fileDialog.setFilterExtensions(new String[] { "*.csv" });
		fileDialog.setFilterNames(new String[] { "CSV files (*.csv)" });
		// Open Dialog and save result of selection
		String selectedFile = fileDialog.open();
		if (selectedFile == null) {
			return null;
		}
		return selectedFile;
	}

	/**
	 * Display an open file dialog and retrieve filename
	 * 
	 * @return filename of selected file
	 */
	private String getOpenFileNameXML() {
		FileDialog fileDialog = new FileDialog(getShell(), SWT.OPEN);
		fileDialog.setText("Select project file");
		fileDialog.setFilterExtensions(new String[] { "*.xml" });
		fileDialog.setFilterNames(new String[] { "XML files (*.xml)" });
		// Open Dialog and save result of selection
		String selectedFile = fileDialog.open();
		if (selectedFile == null) {
			return null;
		}
		return selectedFile;
	}

	protected DataBindingContext initDataBindings() {
		DataBindingContext bindingContext = new DataBindingContext();
		//
		ObservableListContentProvider listContentProvider = new ObservableListContentProvider();
		IObservableMap[] observeMaps = BeansObservables.observeMaps(listContentProvider.getKnownElements(), Task.class, new String[]{"id", "title", "description", "duration", "deadline", "deliverable", "beforeId", "person"});
		tableViewerTasks.setLabelProvider(new ObservableMapLabelProvider(observeMaps));
		tableViewerTasks.setContentProvider(listContentProvider);
		//
		IObservableList projectFlatTasklistObserveList = BeansObservables.observeList(Realm.getDefault(), project, "flatTasklist");
		tableViewerTasks.setInput(projectFlatTasklistObserveList);
		//
		CellEditor cellEditor = new TextCellEditor(tableViewerTasks.getTable());
		IValueProperty cellEditorProperty = CellEditorProperties.control().value(WidgetProperties.text(SWT.Modify));
		IBeanValueProperty valueProperty = BeanProperties.value("title");
		tableViewerColumnTitle.setEditingSupport(ObservableValueEditingSupport.create(tableViewerTasks, bindingContext, cellEditor, cellEditorProperty, valueProperty));
		//
		CellEditor cellEditor_1 = new TextCellEditor(tableViewerTasks.getTable());
		IValueProperty cellEditorProperty_1 = CellEditorProperties.control().value(WidgetProperties.text(SWT.Modify));
		IBeanValueProperty valueProperty_1 = BeanProperties.value("description");
		tableViewerColumnDescription.setEditingSupport(ObservableValueEditingSupport.create(tableViewerTasks, bindingContext, cellEditor_1, cellEditorProperty_1, valueProperty_1));
		//
		CellEditor cellEditor_2 = new TextCellEditor(tableViewerTasks.getTable());
		IValueProperty cellEditorProperty_2 = CellEditorProperties.control().value(WidgetProperties.text(SWT.Modify));
		IBeanValueProperty valueProperty_2 = BeanProperties.value("duration");
		tableViewerColumnDuration.setEditingSupport(ObservableValueEditingSupport.create(tableViewerTasks, bindingContext, cellEditor_2, cellEditorProperty_2, valueProperty_2));
		//
		CellEditor cellEditor_3 = new TextCellEditor(tableViewerTasks.getTable());
		IValueProperty cellEditorProperty_3 = CellEditorProperties.control().value(WidgetProperties.text(SWT.Modify));
		IBeanValueProperty valueProperty_3 = BeanProperties.value("deadline");
		tableViewerColumnDeadline.setEditingSupport(ObservableValueEditingSupport.create(tableViewerTasks, bindingContext, cellEditor_3, cellEditorProperty_3, valueProperty_3));
		//
		CellEditor cellEditor_4 = new TextCellEditor(tableViewerTasks.getTable());
		IValueProperty cellEditorProperty_4 = CellEditorProperties.control().value(WidgetProperties.text(SWT.Modify));
		IBeanValueProperty valueProperty_4 = BeanProperties.value("deliverable");
		tableViewerColumnDeliverable.setEditingSupport(ObservableValueEditingSupport.create(tableViewerTasks, bindingContext, cellEditor_4, cellEditorProperty_4, valueProperty_4));
		//
		CellEditor cellEditor_6 = new TextCellEditor(tableViewerTasks.getTable());
		IValueProperty cellEditorProperty_6 = CellEditorProperties.control().value(WidgetProperties.text(SWT.Modify));
		IBeanValueProperty valueProperty_6 = BeanProperties.value("beforeId");
		tableViewerColumnBeforeId.setEditingSupport(ObservableValueEditingSupport.create(tableViewerTasks, bindingContext, cellEditor_6, cellEditorProperty_6, valueProperty_6));
		//
		CellEditor cellEditor_5 = new TextCellEditor(tableViewerTasks.getTable());
		IValueProperty cellEditorProperty_5 = CellEditorProperties.control().value(WidgetProperties.text(SWT.Modify));
		IBeanValueProperty valueProperty_5 = BeanProperties.value("person");
		tableViewerColumnPerson.setEditingSupport(ObservableValueEditingSupport.create(tableViewerTasks, bindingContext, cellEditor_5, cellEditorProperty_5, valueProperty_5));
		//
		BeansListObservableFactory treeObservableFactory = new BeansListObservableFactory(Task.class, "subtasks");
		TreeBeanAdvisor treeAdvisor = new TreeBeanAdvisor(Task.class, "title", "subtasks", null);
		ObservableListTreeContentProvider treeContentProvider = new ObservableListTreeContentProvider(treeObservableFactory, treeAdvisor);
		treeViewerTasks.setLabelProvider(new TreeObservableLabelProvider(treeContentProvider.getKnownElements(), Task.class, "title", null));
		treeViewerTasks.setContentProvider(treeContentProvider);
		//
		IObservableList projectTasklistObserveList = BeansObservables.observeList(Realm.getDefault(), project, "tasklist");
		treeViewerTasks.setInput(projectTasklistObserveList);
		//
		ObservableListContentProvider listContentProvider_1 = new ObservableListContentProvider();
		IObservableMap[] observeMaps_1 = BeansObservables.observeMaps(listContentProvider_1.getKnownElements(), Person.class, new String[]{"name", "hours", "tasklist"});
		tableViewerPeople.setLabelProvider(new ObservableMapLabelProvider(observeMaps_1));
		tableViewerPeople.setContentProvider(listContentProvider_1);
		//
		IObservableList projectPeopleListObserveList = BeansObservables.observeList(Realm.getDefault(), project, "peopleList");
		tableViewerPeople.setInput(projectPeopleListObserveList);
		//
		return bindingContext;
	}
}
